package com.pkk.penguin.frame.know.java.driven.factorybean.config;

import com.pkk.penguin.frame.know.java.driven.factorybean.bean.Person;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.FactoryBean;

/**
 * @description: 工厂bean生产一个bean
 * @author: peikunkun
 * @create: 2020-08-03 11:26
 **/
@Slf4j
public class PersonFactoryBean implements FactoryBean<Person> {

  /**
   * Return an instance (possibly shared or independent) of the object managed by this factory.
   * <p>As with a {@link BeanFactory}, this allows support for both the
   * Singleton and Prototype design pattern.
   * <p>If this FactoryBean is not fully initialized yet at the time of
   * the call (for example because it is involved in a circular reference), throw a corresponding {@link
   * FactoryBeanNotInitializedException}.
   * <p>As of Spring 2.0, FactoryBeans are allowed to return {@code null}
   * objects. The factory will consider this as normal value to be used; it will not throw a
   * FactoryBeanNotInitializedException in this case anymore. FactoryBean implementations are encouraged to throw
   * FactoryBeanNotInitializedException themselves now, as appropriate.
   *
   * @return an instance of the bean (can be {@code null})
   * @throws Exception in case of creation errors
   * @see FactoryBeanNotInitializedException
   */
  @Override
  public Person getObject() throws Exception {
    log.info(this.getClass().getSimpleName() + " is Call");
    return new Person();
  }

  /**
   * Return the type of object that this FactoryBean creates, or {@code null} if not known in advance.
   * <p>This allows one to check for specific types of beans without
   * instantiating objects, for example on autowiring.
   * <p>In the case of implementations that are creating a singleton object,
   * this method should try to avoid singleton creation as far as possible; it should rather estimate the type in
   * advance. For prototypes, returning a meaningful type here is advisable too.
   * <p>This method can be called <i>before</i> this FactoryBean has
   * been fully initialized. It must not rely on state created during initialization; of course, it can still use such
   * state if available.
   * <p><b>NOTE:</b> Autowiring will simply ignore FactoryBeans that return
   * {@code null} here. Therefore it is highly recommended to implement this method properly, using the current state of
   * the FactoryBean.
   *
   * @return the type of object that this FactoryBean creates, or {@code null} if not known at the time of the call
   * @see ListableBeanFactory#getBeansOfType
   */
  @Override
  public Class<?> getObjectType() {
    return Person.class;
  }

  /**
   * Is the object managed by this factory a singleton? That is, will {@link #getObject()} always return the same object
   * (a reference that can be cached)?
   * <p><b>NOTE:</b> If a FactoryBean indicates to hold a singleton object,
   * the object returned from {@code getObject()} might get cached by the owning BeanFactory. Hence, do not return
   * {@code true} unless the FactoryBean always exposes the same reference.
   * <p>The singleton status of the FactoryBean itself will generally
   * be provided by the owning BeanFactory; usually, it has to be defined as singleton there.
   * <p><b>NOTE:</b> This method returning {@code false} does not
   * necessarily indicate that returned objects are independent instances. An implementation of the extended {@link
   * SmartFactoryBean} interface may explicitly indicate independent instances through its {@link
   * SmartFactoryBean#isPrototype()} method. Plain {@link FactoryBean} implementations which do not implement this
   * extended interface are simply assumed to always return independent instances if the {@code isSingleton()}
   * implementation returns {@code false}.
   * <p>The default implementation returns {@code true}, since a
   * {@code FactoryBean} typically manages a singleton instance.
   *
   * @return whether the exposed object is a singleton
   * @see #getObject()
   * @see SmartFactoryBean#isPrototype()
   */
  /**
   * @Description: 是否为单实例
   * @return: boolean
   * @Author: peikunkun
   * @Date: 2020/8/3 0003 上午 11:29
   */
  @Override
  public boolean isSingleton() {
    return true;
  }
}
